﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using CLEX.Service.DataContracts;

namespace CLEX.Client.Metro.ViewModel.Lattice
{
    public class LatticeEditVM : VMBase
    {
        private readonly IFacade facade;
        private readonly IPopupService popup;
        private readonly TableData table;
        private readonly LatticeState state;
        private readonly ObservableCollection<string> groupByColumns;
        private string selectedGroupByColumn;
        private readonly ObservableCollection<string> notGroupByColumns;
        private string selectedNotGroupByColumn;
        private readonly RelayCommand add;
        private readonly RelayCommand remove;
        private readonly RelayCommand ok;
        private readonly RelayCommand cancel;

        public ObservableCollection<string> GroupByColumns
        {
            get { return groupByColumns; }
        }

        public ObservableCollection<string> NotGroupByColumns
        {
            get { return notGroupByColumns; }
        }

        public string SelectedGroupByColumn
        {
            get { return selectedGroupByColumn; }
            set
            {
                if (selectedGroupByColumn != value)
                {
                    selectedGroupByColumn = value;
                    RaisePropertyChanged("SelectedGroupByColumn");
                    ok.RaiseCanExecuteChanged();
                    cancel.RaiseCanExecuteChanged();
                    add.RaiseCanExecuteChanged();
                    remove.RaiseCanExecuteChanged();
                }
            }
        }

        public string SelectedNotGroupByColumn
        {
            get { return selectedNotGroupByColumn; }
            set
            {
                if (selectedNotGroupByColumn != value)
                {
                    selectedNotGroupByColumn = value;
                    RaisePropertyChanged("SelectedNotGroupByColumn");
                    ok.RaiseCanExecuteChanged();
                    cancel.RaiseCanExecuteChanged();
                    add.RaiseCanExecuteChanged();
                    remove.RaiseCanExecuteChanged();
                }
            }
        }

        public ICommand Add
        {
            get { return add; }
        }

        public ICommand Remove
        {
            get { return remove; }
        }

        public RelayCommand OK
        {
            get { return ok; }
        }

        public RelayCommand Cancel
        {
            get { return cancel; }
        }

        public LatticeEditVM(IFacade facade, IPopupService popup, TableData table, LatticeState state)
        {
            this.facade = facade;
            this.popup = popup;
            this.table = table;
            this.state = state;
            this.groupByColumns = new ObservableCollection<string>(state.LatticeColumns);
            this.notGroupByColumns = new ObservableCollection<string>(table.Columns.Select(p => p.Name).Except(state.LatticeColumns));
            this.add = new RelayCommand(DoAdd, CanAdd);
            this.remove = new RelayCommand(DoRemove, CanRemove);
            this.ok = new RelayCommand(DoOK, CanOK);
            this.cancel = new RelayCommand(DoCancel, CanCancel);
        }

        private void DoAdd()
        {
            var c = selectedNotGroupByColumn;
            notGroupByColumns.Remove(c);
            groupByColumns.Add(c);
            ok.RaiseCanExecuteChanged();
            cancel.RaiseCanExecuteChanged();
        }

        private bool CanAdd()
        {
            return selectedNotGroupByColumn != null;
        }

        private void DoRemove()
        {
            var c = selectedGroupByColumn;
            groupByColumns.Remove(selectedGroupByColumn);
            notGroupByColumns.Add(c);
            ok.RaiseCanExecuteChanged();
            cancel.RaiseCanExecuteChanged();
        }

        private bool CanRemove()
        {
            return selectedGroupByColumn != null;
        }

        private void DoOK()
        {
            state.LatticeColumns = groupByColumns;
            popup.ClosePopup();
        }

        private bool CanOK()
        {
            return groupByColumns.Any();
        }

        private void DoCancel()
        {
            popup.ClosePopup();
        }

        private bool CanCancel()
        {
            return state.LatticeColumns.Any();
        }
    }
}
